home *** CD-ROM | disk | FTP | other *** search
- #include <alloca.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <unistd.h>
-
- #include "newt.h"
- #include "log.h"
- #include "run.h"
- #include "windows.h"
-
- int runProgramRoot(enum runType runType, char * root, char * name,
- char ** args) {
- return runProgramIORoot(runType, root, name, args, NULL, NULL);
- }
-
- int runProgramIO(enum runType runType, char * name, char ** args, char * in,
- char ** out) {
- return runProgramIORoot(runType, NULL, name, args, in, out);
- }
-
- int runProgramIORoot(enum runType runType, char * root, char * name,
- char ** args, char * in, char ** out) {
-
- char * buf;
- int infd, outfd, errfd, status, i;
- int resultfd = 0;
- pid_t pid;
- char ** currarg;
- int inputPipe[2], outputPipe[2];
- char resultbuf[200];
- char * result;
- int resultSize;
- char fullname[200];
-
- /* if "in" is set, it better be short. We assume one write() call is
- enough */
-
- if (root) {
- sprintf(fullname, "%s/%s", root, name);
- } else
- strcpy(fullname, name);
-
- i = 0;
- i = strlen(name) + 50;
-
- currarg = args;
- while (*currarg) {
- i += strlen(*currarg) + 1;
- currarg++;
- }
-
- buf = alloca(i);
-
- if (testing)
- strcpy(buf, "if I weren't testing I would run:\n\n");
- else
- strcpy(buf, "running: ");
-
- strcat(buf, name);
- strcat(buf, " ");
-
- currarg = args;
- while (*currarg) {
- strcat(buf, *currarg);
- strcat(buf, " ");
- currarg++;
- }
-
- if (testing) {
- newtComponent t, f, succeed, fail;
-
- newtOpenWindow(17, 4, 45, 15, "Running");
-
- succeed = newtButton(8, 10, "Succeed");
- fail = newtButton(28, 10, "Fail");
- t = newtTextbox(2, 1, 40, 13, NEWT_TEXTBOX_WRAP | NEWT_TEXTBOX_SCROLL);
- newtTextboxSetText(t, buf);
- f = newtForm(NULL, NULL, 0);
-
- newtFormAddComponents(f, t, succeed, fail, NULL);
-
- t = newtRunForm(f);
-
- newtFormDestroy(f);
- newtPopWindow();
-
- return t == fail;
- }
-
- if (access(fullname, X_OK)) {
- logMessage("cannot run %s: %s", fullname, strerror(errno));
- messageWindow("Error", "I cannot run %s: %s", fullname,
- strerror(errno));
- return -1;
- }
-
-
- logMessage(buf);
-
- if (root)
- logMessage(" root is %s", root);
-
- if (in) {
- pipe(inputPipe);
- write(inputPipe[1], in, strlen(in));
- close(inputPipe[1]);
- infd = inputPipe[0];
- } else {
- infd = open("/dev/null", O_RDONLY);
- }
-
- errfd = open("/dev/tty5", O_APPEND | O_CREAT);
- if (errfd < 0)
- errfd = open("/tmp/exec.log", O_APPEND | O_CREAT);
-
- if (out) {
- pipe(outputPipe);
- outfd = outputPipe[1];
- resultfd = outputPipe[0];
- } else if (runType & RUN_LOG) {
- outfd = open("/dev/tty5", O_RDWR);
- if (outfd < 0)
- outfd = open("/tmp/exec.log", O_APPEND | O_CREAT);
- } else
- outfd = open("/dev/null", O_RDWR);
-
- if (!(pid = fork())) {
- close(0);
- close(1);
- close(2);
-
- if (root) {
- chroot(root);
- chdir("/");
- }
-
- dup2(infd, 0);
- dup2(outfd, 1);
- dup2(errfd, 2);
-
- close(infd);
- close(outfd);
- close(errfd);
- if (out) close(resultfd);
-
- execv(name, args);
- logMessage("exec of %s failed: %s", name, strerror(errno));
- exit(-1);
- }
-
- close(infd);
- close(outfd);
- close(errfd);
-
- if (out) {
- resultSize = 0;
- result = NULL;
-
- do {
- i = read(resultfd, resultbuf, sizeof(resultbuf));
-
- if (!result) {
- result = malloc(i + 1);
- } else
- result = realloc(result, resultSize + i + 1);
- memcpy(result + resultSize, resultbuf, i);
- resultSize += i;
- result[resultSize] = '\0';
- } while (i > 0);
-
- close(resultfd);
- *out = result;
- }
-
- waitpid(pid, &status, 0);
-
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
-
- return -1;
- }
-
- int runProgram(enum runType runType, char * name, char ** args) {
- return runProgramIO(runType, name, args, NULL, NULL);
- }
-